'use strict';


//词法解析构造函数
function Lexer() {

}
/********词法解析函数*******/
Lexer.prototype.lex = function (text) {
    //表达式符号化在这里进行
    this.text = text;//表达式
    this.index = 0;//字符的的索引
    this.ch = undefined;//当前的字符
    this.tokens = [];

    //遍历整个表达式字符串，处理不同的字符
    while (this.index < this.text.length) {
        this.ch = this.text.charAt(this.index);
        if (this.isNumber(this.ch)) {
            this.readNumber();
        }
        else {
            throw 'Unexpected next character: ' + this.ch;
        }
    }
    return this.tokens;
};

//判断是否是Number的函数
Lexer.prototype.isNumber = function (ch) {
    return '0' <= ch && ch <= '9';
};

//读出一串数字，只是读取整数
Lexer.prototype.readNumber = function () {
    var number = '';
    while (this.index < this.text.length) {
        var ch = this.text.charAt(this.index);
        if (this.isNumber(ch)) {
            number += ch;
        }
        else {
            break;
        }
        this.index++;
    }
    this.tokens.push({
        text: number,
        value: Number(number)//此处可以将"012345678"转为12345678
    })
};


/*****语法树生成系统*****/
function AST(lexer) {
    this.lexer = lexer;
}
AST.Program = 'Program';
AST.Literal = 'Literal';


AST.prototype.ast = function (text) {
    this.tokens = this.lexer.lex(text);
    return this.program();
};

AST.prototype.program = function () {
    return {type: AST.Program, body:this.constant()};
};

AST.prototype.constant = function(){
    return {type:AST.Literal,value:this.tokens[0].value};
};

/*******语法树编译系统*********/

function ASTCompiler(astBuilder) {
    this.astBuilder = astBuilder;
    this.state = {body:[]};
}


ASTCompiler.prototype.compile = function (text) {
    var ast = this.astBuilder.ast(text);
    this.state = {body:[]};
    this.recurse(ast);
    return new Function(this.state.body.join(''));
};

ASTCompiler.prototype.recurse = function(ast){
    switch(ast.type){
        case AST.Program:
            this.state.body.push('return ',this.recurse(ast.body),';');
        case AST.Literal:
            return ast.value;
    }
};




//语法分析系统，是将上面的结合起来

function Parser(lexer) {
    this.lexer = lexer;
    this.ast = new AST(this.lexer);
    this.astCompiler = new ASTCompiler(this.ast);
}

Parser.prototype.parse = function (text) {
    return this.astCompiler.compile(text);
};

function parse(expr) {
    var lexer = new Lexer();
    var parser = new Parser(lexer);
    return parser.parse(expr);
}
module.exports = parse;
